<?php
/**
 * 
 */
namespace TwinPeaks\Stdlib\Storage\KeyValue;
use TwinPeaks\Stdlib\Storage as Storage;

require __DIR__ . '/../IKeyValue.php';

class CFilesystem implements Storage\IKeyValue
{
	const DATABASE_MODE_FLAT = 1;
	const DATABASE_MODE_MONTH = 2;
	
	/**
	 * 
	 * @var integer Specify how data will be organized
	 */
	private $mode;
	
	/**
	 * @var Pathname to a directory where data will be stored. Trailing slash is required
	 */
	private $baseDir;
	
	/**
	 * @var string
	 */
	private $filenamePrefix;
	
	/**
	 * @return
	 */
	function __construct($baseDir, $prefix = '', $mode = self::DATABASE_MODE_FLAT)
	{
		$this->baseDir = $baseDir;
		if (!is_dir($this->getBaseDir()))
			mkdir($this->getBaseDir(), 0777, true);
		$this->filenamePrefix = $prefix;
		$this->mode = $mode;
	}
	
	/**
	 * @return string
	 */
	function getBaseDir()
	{
		return $this->baseDir;
	}
	
	/**
	 * 
	 */
	final function getMode()
	{
		return $this->mode;
	}

	/**
	 * @return string|null
	 */
	function get($key)
	{
		$filename = $this->getFilename($key);
		$fd = fopen($filename, 'r');
		if (!$fd)
			return null;
		$value = fread($fd, filesize($filename));
		fclose($fd);
		return $value;
	}

	/**
	 * @return void
	 */
	function set($key, $value)
	{
		$fd = fopen($this->getFilename($key), 'w');
		if ($fd)
		{
			fwrite($fd, strval($value));
			fclose($fd);
		}	
	}
	
	/**
	 * @return
	 */
	function remove($key)
	{
		if ($this->has($key))
			unlink($this->getFilename($key));
	}

	/**
	 * @return boolean
	 */
	function has($key)
	{
		return file_exists($this->getFilename($key));
	}
	
	/**
	 * @return string Filename for a key
	 */
	private function getFilename($key)
	{
		$filename = $this->getBaseDir();
		$filename .= $this->filenamePrefix . md5($key); 
		return $filename;
	}
}
